Although you can certainly use WebClient in a Silverlight application, it’s not generally necessary with bitmaps because the bitmap-related classes already implement asynchronous downloading.
However, once you begin investigating the Image element, it may seem a little confusing. The Image element is not the bitmap; the Image element merely displays the bitmap. In the uses you’ve seen so far, the Source property of Image has been set to a relative file path or a URL:
<Image Source="Images/Hello.png" />
<Image Source="http://www.charlespetzold.com/Media/HelloWP7.jpg" />
You might have assumed that this Source property was of type string. Sorry, not even close! You’re actually seeing XAML syntax that hides some extensive activity behind the scenes. The Source property is really of type ImageSource, an abstract class from which derives BitmapSource, another abstract class but one that defines a method named SetSource that allows loading the bitmap from a Stream object.
From BitmapSource derives BitmapImage, which supports a constructor that accepts a Uri object and also includes a UriSource property of type Uri. The SilverlightTapToDownload1
project mimics a program that needs to download a bitmap whose URL is
known only at runtime. The XAML contains an Image element with no bitmap to display:
Example 1. Silverlight Project: SilverlightTapToDownload1 File: MainPage.xaml (excerpt)
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <Image Name="img" /> </Grid>
|
BitmapImage requires a using directive for the System.Windows.Media.Imaging namespace. When MainPage gets a tap, it creates a BitmapImage from the UriSource property of the Image: object and sets that to the
Example 2. Silverlight Project: SilverlightTapToDownload1 File: MainPage.xaml.cs (excerpt)
protected override void OnManipulationStarted(ManipulationStartedEventArgs args) { Uri uri = new Uri("http://www.charlespetzold.com/Media/HelloWP7.jpg"); BitmapImage bmp = new BitmapImage(uri); img.Source = bmp;
args.Complete(); args.Handled = true; base.OnManipulationStarted(args); }
|
Remember to tap the screen to initiate the download!
The BitmapImage class defines ImageOpened and ImageFailed events (which the Image element also duplicates) and also includes a DownloadProgess event.
If you want to explicitly use WebClient in a Silverlight
program, you can do that as well, as the next project demonstrates. The
SilverlightTapToDownload2.xaml file is the same as SilverlightTapToDownload1.xaml. The code-behind file uses WebClient much like the earlier XNA program:
Example 3. Silverlight Project: SilverlightTapToDownload2 File: MainPage.xaml.cs (excerpt)
protected override void OnManipulationStarted(ManipulationStartedEventArgs args) { WebClient webClient = new WebClient(); webClient.OpenReadCompleted += OnWebClientOpenReadCompleted; webClient.OpenReadAsync(new Uri("http://www.charlespetzold.com/Media/HelloWP7. jpg"));
args.Complete(); args.Handled = true; base.OnManipulationStarted(args); }
void OnWebClientOpenReadCompleted(object sender, OpenReadCompletedEventArgs args) { if (!args.Cancelled && args.Error == null) { BitmapImage bmp = new BitmapImage(); bmp.SetSource(args.Result); img.Source = bmp; } }
|
Notice the use of SetSource to create the bitmap from the Stream object.